import { menu } from "../../decorator";

const { ccclass, property } = cc._decorator;

enum TimeEnum {
    none = 0,
    onLoad = 1,
    start = 2,
    onEnable = 3,
    onDisable = 4,
    onDestroy = 5
}

@ccclass
@menu(__filename)
export default class initChildren extends cc.Component {
    @property
    protected _target: cc.Node = null
    @property({
        type: cc.Node,
        tooltip: '默认是本节点'
    })
    get target() {
        if (this._target && !this._target.isValid) {
            this._target = null;
        }
        return this._target || this.node;
    }
    set target(value) {
        this._target = value;
    }

    @property({
        type: cc.Enum(TimeEnum),
        tooltip: '触发的时机'
    })
    time: TimeEnum = TimeEnum.onDestroy;

    @property({
        tooltip: '初始化的脚本名'
    })
    childComName: string = 'cc.Component';

    @property({
        tooltip: '脚本内的哪个方法'
    })
    childComFun: string = 'init';

    @property({ tooltip: '格式：数组JSON.stringify后的字符串' })
    args: string = 'null';

    onLoad() {
        if (timeEnum[this.time] === 'onLoad') {
            this.init();
        }
    }
    start() {
        if (timeEnum[this.time] === 'start') {
            this.init();
        }
    }
    onEnable() {
        if (timeEnum[this.time] === 'onEnable') {
            this.init();
        }
    }
    onDisable() {
        if (timeEnum[this.time] === 'onDisable') {
            this.init();
        }
    }
    onDestroy() {
        if (timeEnum[this.time] === 'onDestroy') {
            this.init();
        }
    }

    private _parse(param) {
        if (!param) return null;
        if (CC_DEBUG) {
            try {
                return JSON.parse(param);
            } catch (e) {
                cc.error('args参数错误');
                return 'args参数错误';
            }
        } else {
            return JSON.parse(param);;
        }
        return null;
    }

    init(): void
    init(data: any): void
    init(handleCallback: (com: cc.Component, index: number) => any): void
    init<T>(data: T, handleCallback: (com: cc.Component, index: number, data: T) => any): void
    init(...args) {
        let data = null;
        let handle = null;

        if (args.length === 2) {
            data = args[0];
            handle = args[1];
        } else if (args.length === 1) {
            if (typeof args[0] === 'function') {
                handle = args[0];
                data = this._parse(this.args);
            } else {
                data = args[0];
            }
        } else {
            data = this._parse(this.args);
        }

        const comArr = this.target.getComponentsInChildren(this.childComName);
        for (let index = 0; index < comArr.length; index++) {
            const com = comArr[index];
            com[this.childComFun](index, data);
            handle && handle(com, index, data);
        }
    }
}
